package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.CartInfoService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.model.ProductSku;
import com.spzx.product.vo.SkuPriceVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: atguigu
 * @create: 2025-05-07 15:51
 */
@Service
public class CartInfoServiceImpl implements CartInfoService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductService remoteProductService;

    /**
     * 将指定商品ID对应数量加入到购物车
     *
     * @param skuId
     * @param num
     */
    @Override
    public void addToCart(Long skuId, Integer num) {
        //1. 判断购物车中是否有该商品
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = this.getCartKey(userId);
        String field = skuId.toString();
        //写法一
        //Boolean exists = redisTemplate.opsForHash().hasKey(cartKey, field);
        //写法二：创建BoundHashOperations对象
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        Boolean exists = hashOps.hasKey(field);
        //2. 如果商品存在，则更新数量 单品数量上限99
        if (exists) {
            CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(cartKey, field);
            Integer skuNum = cartInfo.getSkuNum();
            cartInfo.setSkuNum(skuNum + num > 99 ? 99 : skuNum + num);
            cartInfo.setUpdateTime(new Date());
            //redisTemplate.opsForHash().put(cartKey, field, cartInfo);
            hashOps.put(field, cartInfo);
        } else {
            //3.如果商品不存在，则构建购物车商品对象，限制最多加购商品数量50个，并保存到购物车中
            //3.1 业务校验
            //Long count = redisTemplate.opsForHash().size(cartKey);
            Long count = hashOps.size();
            if (count > 50) {
                throw new RuntimeException("最多只能加入50个商品");
            }
            //3.2 远程调用商品服务获取商品信息
            R<ProductSku> r = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (r.getCode() != 200) {
                throw new ServiceException("远程调用商品服务失败，原因：" + r.getMsg());
            }
            ProductSku productSku = r.getData();
            //3.3 构建购物车商品对象
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(productSku.getId());
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(num > 99 ? 99 : num);
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setCreateTime(new Date());
            //3.4 将购物车商品写入Redis
            //redisTemplate.opsForHash().put(cartKey, field, cartInfo);
            hashOps.put(field, cartInfo);
        }
    }

    /**
     * 查询购物车商品列表
     *
     * @return
     */
    @Override
    public List<CartInfo> cartList() {
        //1.确定当前用户购物车的key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.获取购物车Hash结构中Value列表对应就是购物车商品列表
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();

        //3.如果有值，按照加入购物车时间进行降序，并返回
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            //使用Stream流进行排序
            List<CartInfo> collect = cartInfoList
                    .stream()
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return collect;
        }
        return null;
    }

    /**
     * 选中或取消选中状态
     *
     * @param skuId
     * @param isChecked
     * @return
     */
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //1.确定当前用户购物车的key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.确定购物车上商品field
        String field = skuId.toString();
        //3.获取购物车中商品
        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(cartKey, field);
        //4.更新购物车商品选中状态
        cartInfo.setIsChecked(isChecked);
        redisTemplate.opsForHash().put(cartKey, field, cartInfo);
    }

    /**
     * 全部选中或取消选中状态
     *
     * @param isChecked
     * @return
     */
    @Override
    public void allCheckCart(Integer isChecked) {
        //1.确定当前用户购物车的key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.获取购物车Hash结构中Value列表对应就是购物车商品列表
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.forEach(cartInfo -> {
                //更新选中状态
                cartInfo.setIsChecked(isChecked);
                hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
            });
        }
    }

    /**
     * 删除购物车商品
     *
     * @param skuId
     * @return
     */
    @Override
    public void deleteCart(Long skuId) {
        //1.确定当前用户购物车的key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.获取购物车Hash结构中Value列表对应就是购物车商品列表
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //3.删除指定购物车商品
        String field = skuId.toString();
        Boolean exists = hashOps.hasKey(field);
        if (exists) {
            hashOps.delete(field);
        }
    }

    /**
     * 清空购物车
     */
    @Override
    public void clearCart() {
        //1.确定当前用户购物车的key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.删除用户购物车key
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList() {
        //1.确定当前用户购物车的key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.获取购物车Hash结构中Value列表对应就是购物车商品列表
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //3.获取选中商品列表
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            List<CartInfo> checkedCartList = cartInfoList
                    .stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .collect(Collectors.toList());
            return checkedCartList;
        }
        return null;
    }

    /**
     * 更新购物车价格
     *
     * @return
     */
    @Override
    public Boolean updateCartPrice() {
        //1.确定当前用户购物车的key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.获取购物车Hash结构中Value列表对应就是购物车商品列表
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //3.获取选中商品列表
        List<CartInfo> cartInfoList = hashOps.values();
        //4.遍历更新价格
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                //4.1 远程调用商品服务获取实时价格
                R<SkuPriceVo> r = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
                if (R.FAIL == r.getCode()) {
                    throw new ServiceException("获取商品实时价格异常:" + r.getMsg());
                }

                //4.2 写入Redis购物车
                SkuPriceVo skuPriceVo = r.getData();
                cartInfo.setSkuPrice(skuPriceVo.getSalePrice());
                hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
            }
        }
        return null;
    }

    /**
     * 清理选中购物车商品
     *
     * @return
     */
    @Override
    public Boolean deleteCartCheckedList() {
        //1.确定当前用户购物车的key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.获取购物车Hash结构中Value列表对应就是购物车商品列表
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //3.获取选中商品列表
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList
                    .stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .forEach(cartInfo -> {
                        hashOps.delete(cartInfo.getSkuId().toString());
                    });
        }
        return true;
    }


    private String getCartKey(Long userId) {
        //定义key user:userId:cart
        return "user:cart:" + userId;
    }
}
